package com.firefly.web.utils;

import com.firefly.service.command.common.AliyunOssCommand;
import com.firefly.util.handle.CommonResult;
import com.firefly.util.handle.FireflyException;
import com.firefly.util.utils.LocalDateUtils;
import com.firefly.util.utils.ResultUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * @description: oss文件上传功能
 * @author: lzg(萤火科技 ： 854378082 @ qq.com)
 * @date: 2023/5/15
 **/
@Component
public class OssUtils {
    /**
     * 本地文件上传目录
     */
    @Value("${upload.dir}")
    public String uploadDir;
    private final AliyunOssCommand aliyunOssCommand;
    @Autowired
    public OssUtils(AliyunOssCommand aliyunOssCommand){
        this.aliyunOssCommand = aliyunOssCommand;
    }
    // 以文件流上传
    public CommonResult uploadStream(MultipartFile multipartFile,String dir) throws IOException {
        // 上传参数校验 + 路径生成
        Map fileMap = fileValidate(multipartFile,dir);
        dir = (String) fileMap.get("dir");
        String fileName = (String) fileMap.get("fileName");
        // 获取文件对象
        aliyunOssCommand.uploadStream(multipartFile.getInputStream(),dir + fileName);
        Map<String, Object> result = new HashMap<>();
        result.put("url", "/" + dir + fileName);
        result.put("filename", fileName);
        return ResultUtil.success(result);
    }
    // 本地文件上传
    public CommonResult uploadFile(String filePath) {
        // 默认是放到upload路径下，要替换一次，防止二次追加
        String allPath = uploadDir.concat(filePath.replace("upload/",""));
        // 判断文件存不存在
        File testFile = new File(allPath);
        if(!testFile.exists()) {
            throw new FireflyException(403,"文件不存在");
        }
        aliyunOssCommand.uploadFile(allPath,filePath);
        Map<String, Object> result = new HashMap<>();
        result.put("url", "/" + filePath);
        return ResultUtil.success(result);
    }
    // 以文件形式上传
    public CommonResult uploadTmpFile(MultipartFile multipartFile,String dir) throws IOException {
        // 上传参数校验 + 路径生成
        Map fileMap = fileValidate(multipartFile,dir);
        dir = (String) fileMap.get("dir");
        // 文件夹不存在，则新建
        String basePath = uploadDir.concat("tmpFiles/");
        File fileExist = new File(basePath);
        if (!fileExist.exists()) {
            fileExist.mkdirs();
        }
        // 创建一个新的文件对象，并且删除临时文件
        File newFile = new File(basePath,(String) fileMap.get("originalFilename"));
        FileOutputStream os = new FileOutputStream(newFile);
        os.write(multipartFile.getBytes());
        os.close();
        String fileName = (String) fileMap.get("fileName");
        // 上传到oss
        aliyunOssCommand.uploadTmpFile(newFile, dir + fileName);
        newFile.delete();
        // 返回
        Map<String, Object> result = new HashMap<>();
        result.put("url", "/" + dir + fileName);
        result.put("filename", fileName);
        return ResultUtil.success(result);
    }
    // 文件上传校验部分统一方法 + 生成文件路径
    public Map fileValidate(MultipartFile multipartFile,String dir){
        if (multipartFile == null || multipartFile.isEmpty()) {
            throw new FireflyException(403,"请选择文件");
        }
        // 获取文件的名称
        String originalFilename = multipartFile.getOriginalFilename();
        // 文件后缀 例如：.png
        String fileSuffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        // 查检文件后缀是否允许上传
        List suffixList = new ArrayList<String>(Arrays.asList(".jpg", ".jpeg", ".gif", ".png", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".rar", ".zip", ".swf", ".apk", ".mp4", ".mp3", ".avi"));
        if (suffixList.contains(fileSuffix) == false) {
            throw new FireflyException(403,"不允许上传的文件类型");
        }
        // uuid 生成文件名
        String fileName = String.valueOf(UUID.randomUUID()) + fileSuffix;
        // 这里是个坑，阿里云文件地址不能以 / 开头
        dir = StringUtils.isBlank(dir) ? "upload/images/" : ("upload/" + dir + "/");
        dir += LocalDateUtils.getLocalDateUnsignedStr() + "/";
        Map result = new HashMap<>();
        result.put("dir",dir);
        result.put("originalFilename",originalFilename);
        result.put("fileName",fileName);
        return result;
    }
}
